﻿#if !UNITY_IOS || HUpdate
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.Networking;
using SDK.Scripts.App;

namespace UnityModule
{
    public sealed partial class DownloadComponent : SingletonBehaviour<DownloadComponent>
    {
        /// <summary>
        /// app正在退出
        /// </summary>
        public static bool IsAppQuit = false;

        /// <summary>
        /// 全速下载
        /// </summary>
        public bool IsFullSpeed
        {
            get
            {
                return DownloadClientConfig.IsFullSpeed;
            }
            set
            {
                DownloadClientConfig.IsFullSpeed = value;
                if (value)
                {
                    DownloadClientConfig.LowTaskMaxRunningCount = 2;
                }
                else
                {
                    DownloadClientConfig.LowTaskMaxRunningCount = 1;
                }
            }
        }

        /// <summary>
        /// 非全速下载时的速度限制
        /// </summary>
        public int SpeedLimit
        {
            get
            {
                return DownloadClientConfig.ThreadSpeedLimit;
            }
            set
            {
                DownloadClientConfig.ThreadSpeedLimit = value;
            }
        }

        /// <summary>
        /// 下载更新资源完成回调
        /// </summary>
        private Action m_OnFinish;

        private void OnAppQuit()
        {
            IsAppQuit = true;

            foreach (var item in m_DicDownloading.Values)
            {
                item.Dispose();
            }
            m_DicDownloading.Clear();
            if (m_DLoadZipTask != null)
            {
                m_DLoadZipTask.Dispose();
            }
        }

        private void OnDestroy()
        {
            OnAppQuit();
        }

        public void Init()
        {
            DownloadClientConfig.InitConfig();

            Application.quitting += OnAppQuit;
        }

        public class ZipData
        {
            public int ret;
            public string msg;
            public string data;
        }

        int GetPlatInt()
        {
            if(ApplicationPath.PlatformName.Equals("android"))
            {
                return 0;
            }
            if (ApplicationPath.PlatformName.Equals("ios"))
            {
                return 1;
            }
            return 2;
        }
        /// <summary>
        /// 开始下载更新资源
        /// </summary>
        /// <param name="onPredownloadFinish"></param>
        public void StartDownload(Action onFinish)
        {
            m_failCount = 0;
            m_OnFinish = onFinish;
            // Debug.LogError(UpdateSettings.Instance.CdnUrl + ApplicationPath.VersionInfoFile);
            // Debug.LogError(UpdateSettings.Instance.UpdateUrl);
            StartCoroutine(LoadWebCfg(UpdateSettings.Instance.CdnUrl + ApplicationPath.VersionInfoFile , (arg) =>
            {
                if(!string.IsNullOrEmpty(arg))
                {
                    PanelLoad.Instance.SetVersionInfo(arg);
                }                
            }, (exception) =>
            {
            }));

            if (string.IsNullOrEmpty(UpdateSettings.Instance.UpdateUrl))
            {
                var plat = SDK.Scripts.App.GameSDK.GamePlat;
                string url_zip = $"http://gw.{plat.Domain}/game/diffPackage?userId={plat.UserID}&gameId={plat.GameId}&oldVer={plat.GameVersion}&newVer={VersionComponent.Instance.TargetVersion}&path={m_dloadUrl}&platform={GetPlatInt()}";
                // Debug.LogError(url_zip);
                StartCoroutine(LoadWebCfg(url_zip, (arg) =>
                {
                    Report.SendEvent((int)ReportStep.ReqZip, "1");
                    try
                    {
                        ZipData zipData = JsonUtility.FromJson<ZipData>(arg);
                        if (zipData.ret == 1 && !string.IsNullOrEmpty(zipData.data))
                        {
                            string dat = zipData.data;
                            int index = dat.LastIndexOf('/');
                            string url = dat.Substring(0, index + 1);                            
                            m_zipName = dat.Substring(index + 1, dat.Length - index - 1);
                            //Debug.LogError(url + m_zipName);
                            DLoadZip(url, m_zipName);
                        }
                        else
                        {
                            DLoadNoZip();
                        }
                    }
                    catch (Exception)
                    {
                        Report.SendEvent((int)ReportStep.ReqZip, "3");
                        DLoadNoZip();
                    }
                }, (exception) =>
                {
                    Report.SendEvent((int)ReportStep.ReqZip, "4");
                    DLoadNoZip();
                }));
            }
            else
            {
                DLoadNoZip();
            }               
        }

        void DLoadNoZip()
        {
#if UNITY_IOS
            //对比streamingAsset 内的资源 和 cdn的资源
            Dictionary<string, AssetBundleInfoV2> BundleInfos = VersionComponent.Instance.CdnBundleInfos;
            Dictionary<string, string> BundleHash = VersionComponent.Instance.CdnBundleInfosWithHash;

            foreach (var item in LocalBundleInfosWithHash)
            {
                if (BundleHash.TryGetValue(item.Key, out string abName))
                {
                    if (BundleInfos.TryGetValue(abName, out AssetBundleInfoV2 info))
                    {
                        info.pathType = 2;
                    }
                }
            }
#endif
            m_preDownloadList.Clear();
            m_bgDownloadList.Clear();
            CheckDownloadList(VersionComponent.Instance.CdnBundleInfos.Values.GetEnumerator());
            PreDownload();
        }


        IEnumerator LoadWebCfg(string url, Action<string> onSuccess, Action<string> onFailed)
        {
            using (UnityWebRequest wwwGetInfo = UnityWebRequest.Get(url))
            {
                wwwGetInfo.timeout = 5;
                yield return wwwGetInfo.SendWebRequest();
                if (string.IsNullOrEmpty(wwwGetInfo.error))
                {
                    string json = wwwGetInfo.downloadHandler.text;
                    onSuccess?.Invoke(json);
                }
                else
                {
                    onFailed?.Invoke(wwwGetInfo.error);
                }
            }
        }

        //下载指定ab
        public void Download(AssetBundleInfoV2 bundleInfo, Action<string, string> callback, Action<long, long> progress)
        {
            AddDownloadTask(bundleInfo, callback, progress, true);
        }
        
        /// <summary>
        /// 是否在下载中
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public bool IsDownloading(string fileName)
        {
            return m_DicDownloading.ContainsKey(fileName);
        }
        
        private void Update()
        {
            CheckQueueDownload();
        }
    }
}
#endif